/**
 * 
 */
package com.photoinfo.app;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;

import com.photoinfo.app.vo.Camera;
import com.photoinfo.app.vo.CameraSettings;
import com.photoinfo.app.vo.Description;
import com.photoinfo.app.vo.Equipment;
import com.photoinfo.app.vo.Filter;
import com.photoinfo.app.vo.Lens;
import com.photoinfo.app.vo.Location;
import com.photoinfo.app.vo.Photo;
import com.photoinfo.app.vo.Tripod;
import com.photoinfo.app.vo.TripodHead;

/**
 * @author robh
 * 
 * The Basic Buisness Class of the App holds
 * 
 */
public class PhotoInfoApp implements Serializable {

	private static final long serialVersionUID = 1870925102313072231L;

	public static final String DATA = "photoinfo.dat";

	public static int[] ISOs = { 50, 100, 200, 400, 800, 1600, 3200 };

	public static float[] SHUTTERSPEEDs = { 4000, 3200, 2500, 2000, 1600, 1250,
			1000, 800, 640, 500, 400, 320, 250, 200, 160, 125, 100, 80, 60, 50,
			40, 30, 25, 20, 15, 13, 10, 8, 6, 5, 4, 0.3f, 0.4f, 0.5f, 0.6f,
			0.8f, 1, 1.3f, 1.6f, 2, 2.5f, 3.2f, 4, 5, 6, 8, 10, 13, 15, 20, 25,
			30 };

	public static float[] APERTURE = { 1, 1.2f, 1.4f, 2, 2.8f, 4, 5.6f, 8, 11,
			16, 22, 32 };

	public static int[] FOCAL_LENGTH = { 10, 17, 35, 50, 70, 150, 200 };

	private Description description;

	private List<String> additionalInfo;

	private CameraSettings cameraSettings;

	private Photo photo;

	private List<Location> locations;

	private List<Camera> cameras;

	private List<Lens> lenses;

	private List<Filter> filters;

	private List<String> flashModes;

	private List<Tripod> tripods;

	private List<TripodHead> tripodHeads;

	private ModelComparator modelComparator;
	
	private MakeComparator markComparator;

	public PhotoInfoApp() {
		modelComparator = new ModelComparator();
		markComparator = new MakeComparator();

		additionalInfo = new ArrayList<String>();
		locations = new ArrayList<Location>();
		cameras = new ArrayList<Camera>();
		lenses = new ArrayList<Lens>();
		filters = new ArrayList<Filter>();
		flashModes = new ArrayList<String>();
		tripods = new ArrayList<Tripod>();
		tripodHeads = new ArrayList<TripodHead>();
	}

	public Description getDescription() {
		return description;
	}

	public void setDescription(Description description) {
		this.description = description;
	}

	public List<String> getAdditionalInfo() {
		return additionalInfo;
	}

	public void setAdditionalInfo(List<String> additionalInfo) {
		this.additionalInfo = additionalInfo;
	}

	public CameraSettings getCameraSettings() {
		return cameraSettings;
	}

	public void setCameraSettings(CameraSettings cameraSettings) {
		this.cameraSettings = cameraSettings;
	}

	public Photo getPhoto() {
		return photo;
	}

	public void setPhoto(Photo photo) {
		this.photo = photo;
	}

	public List<Location> getLocations() {
		return locations;
	}

	public void setLocations(List<Location> locations) {
		this.locations = locations;
	}

	public List<Camera> getCameras() {
		return cameras;
	}

	public void setCameras(List<Camera> cameras) {
		this.cameras = cameras;
	}

	public List<Lens> getLenses() {
		return lenses;
	}

	public void setLenses(List<Lens> lenses) {
		this.lenses = lenses;
	}

	public List<String> getFlashModes() {
		return flashModes;
	}

	public void setFlashModes(List<String> flashModes) {
		this.flashModes = flashModes;
	}

	public List<Tripod> getTripods() {
		return tripods;
	}

	public void setTripods(List<Tripod> tripods) {
		this.tripods = tripods;
	}

	public List<TripodHead> getTripodHeads() {
		return tripodHeads;
	}

	public void setTripodHeads(List<TripodHead> tripodHeads) {
		this.tripodHeads = tripodHeads;
	}

	public List<Filter> getFilters() {
		return filters;
	}

	public void setFilters(List<Filter> filters) {
		this.filters = filters;
	}

	public ModelComparator getListComp() {
		return modelComparator;
	}

	public void setListComp(ModelComparator listComp) {
		this.modelComparator = listComp;
	}

	public MakeComparator getMarkComparator() {
		return markComparator;
	}

	public void setMarkComparator(MakeComparator markComparator) {
		this.markComparator = markComparator;
	}

	/**
	 * Adding a new Equipment Object like Camera,Lens,Filter..
	 * @FIXME Generic algorithm could be better to aviod the list as a parameter
	 * 
	 * @param <T>
	 * @param equipment
	 * @param list
	 * @return true/false
	 */
	public <T> boolean addEquipment(T equipment, List<T> list) {
		if (!containsEquipment(equipment, list))
			return list.add(equipment);
		return false;
	}

	/**
	 * removes Object from the list
	 * 
	 * @param <T>
	 * @param equipment
	 * @param list
	 */
	public <T> boolean removeEquipment(T equipment, List<T> list) {
		return list.remove(equipment);
	}

	/**
	 * removes Object via its index from the list
	 * 
	 * @param <T>
	 * @param equipment
	 * @param list
	 */
	public <T> T removeEquipment(int index, List<T> list) {
		return list.remove(index);
	}

	/**
	 * checks if the Object already exists in the list
	 * 
	 * @param <T>
	 * @param equipment
	 * @param list
	 */
	public <T> boolean containsEquipment(T equipment, List<T> list) {
		return list.contains(equipment);
	}
}

/**
 * Class for Sorting the Equipment Lists by Model (Camera, Filter...)
 * 
 * @author rob
 */
class ModelComparator implements Comparator<Equipment>, Serializable {

	private static final long serialVersionUID = -5448551662130276078L;

	public int compare(Equipment arg0, Equipment arg1) {
		return arg0.getModel().compareToIgnoreCase(arg1.getModel());
	}
}

/**
 * Class for Sorting the Equipment Lists by Make (Camera, Filter...)
 * 
 * @author rob
 */
class MakeComparator implements Comparator<Equipment>, Serializable {
	
	private static final long serialVersionUID = 514405808287688975L;

	public int compare(Equipment arg0, Equipment arg1) {
		return arg0.getMake().compareToIgnoreCase(arg1.getMake());
	}
}
